/*
 * tokenGetter.c
 *
 *  Created on: Apr 24, 2014
 *      Author: Hercules
 */
#include "tokenGetter.h"
Token* getNextToken(FILE *program_file, Token* last_token_read) {
	char read_char = '\0';
	Token* new_token;
	int token_size = 0;

	new_token = (Token*) malloc(sizeof(Token));

	while (token_size < 100) {
		read_char = fgetc(program_file);
		if (read_char == ';') { //Se o caracter lido == ';' ignora o comentario
			ignoreComment(program_file);
			if (last_token_read != NULL) {
				last_token_read->token_delimiter = '\n';
			}
		} else if (feof(program_file)) {
			if (token_size == 0) { // Se ja estiver no final do arquivo e um novo token for solicitado retorna null
				return NULL;
			} else { // Se o token for terminado com o final do arquivo retorna o token com separator = '\0'
				new_token->token_string[token_size] = '\0';
				new_token->token_delimiter = '\0';
				strToUpper(new_token->token_string);
				return new_token;
			}
		} else if (read_char == '\n') {
			if (last_token_read != NULL && token_size == 0) {
				last_token_read->token_delimiter = '\n';
			} else if (token_size != 0) {
				new_token->token_string[token_size] = '\0';
				new_token->token_delimiter = read_char;
				strToUpper(new_token->token_string);
				return new_token;
			}
		} else if (read_char == ' ' || read_char == '\t') {
			if (token_size != 0) { // Se encontrar um espaco, tabulacao ou enter no inicio do token o mesmo e ignorado
				new_token->token_string[token_size] = '\0';
				new_token->token_delimiter = read_char;
				strToUpper(new_token->token_string);
				return new_token;
			}
		} else if (read_char == ':' || read_char == ',') {
			new_token->token_string[token_size] = '\0';
			new_token->token_delimiter = read_char;
			strToUpper(new_token->token_string);
			return new_token;

		} else {
			new_token->token_string[token_size++] = read_char;
		}
	}
	strToUpper(new_token->token_string);
	return new_token;
}
char * strToUpper(char *str) {
	int i = 0;
	while (str[i] != '\0') {
		str[i] = toupper(str[i]);
		i++;
	}
	return str;
}
TokenList* getTokenList(FILE* program_file) {
	TokenList* to_return;
	to_return = (TokenList*) malloc(sizeof(TokenList));
	to_return->token = NULL;
	to_return->next = NULL;

	Token* last_read_token = NULL;
	Token* read_token = NULL;
	TokenList *last_token_node = NULL;

	while ((read_token = getNextToken(program_file, last_read_token)) != NULL) { //Enquanto existirem tokens a serem lidos

		if (last_token_node == NULL) { //caso seja o primeiro elemento da lista
			to_return->next = NULL;
			to_return->last = NULL;
			to_return->token = read_token;
			last_token_node = to_return;
		} else {
			TokenList *new_token_node = (TokenList*) malloc(sizeof(TokenList));
			new_token_node->next = NULL;
			new_token_node->last = last_token_node;
			new_token_node->token = read_token;
			last_token_node->next = new_token_node;
			last_token_node = new_token_node;
		}
		last_read_token = read_token;
	}
	return to_return;
}

void ignoreComment(FILE* program_file) {
	char read_char = '\0';
	while (!feof(program_file) && read_char != '\n') { //Ignora os caracteres entre ; e o '\n' ou final do arquivo
		read_char = fgetc(program_file);
	}
}
